#pragma GCC diagnostic error "-Wshadow"

#include <windows.h>
#include <gl/glew.h>
#define GLFW_DLL
#include <GL/glfw.h>

#include "client.h"
#include "gamestate.h"
#include "luainterface.h"
#include "matrixstack/matrixstack.h"
#include "resourcemanager.h"
#include "simulation.h"

#include "gui/gui.h"
#include "gui/guimessage.h"

#include "renderer/renderer.h"

void GLFWCALL KeyCallback(int key, int action){
    bool press = action==GLFW_PRESS ? true : false;
    client->KeyDown(key, press);
}

void GLFWCALL MouseMoveCallback(int x, int y){
    client->SetMousePosition(x, y);
    client->MouseMoved();
}

void GLFWCALL MouseClickCallback(int button, int action){
    if(action==GLFW_PRESS){
        client->Click(button);
    }
}

int main( void ){
    int running = GL_TRUE;
    int lastTime;
    int dt;
    int width = 1600;
    int height = 900;
    GLint error;

    // Initialize GLFW
    if( !glfwInit() ){
        exit( EXIT_FAILURE );
    }
    // Open an OpenGL window
    if( !glfwOpenWindow( width, height, 0,0,0,0,0,0, GLFW_WINDOW ) ){
        glfwTerminate();
        exit( EXIT_FAILURE );
    }

    if(glewInit()==GLEW_OK){
        std::cout<<"GLEW init ok\n";
    }
    else{
        std::cout<<"GLEW init NOT ok\n";
    }


    client = new Client();
    renderer = new Renderer();
    guiStack = new MatrixStack();

    client->GLHeight = height;
    client->GLWidth = width;

    glewInit();

    lua.Init();

    resourceManager = new ResourceManager();
    resourceManager->LoadAllData();

    gamestate = new GameState();
    simulation = new Simulation();


    gui = new GUI();
    gamestate->Initialise();
    simulation->Initialise();

    renderer->Initialise();
    renderer->Resize(width, height);
    client->Initialise(0, true);
    gui->Initialise(client->GLWidth, client->GLHeight);

    glfwSetMouseButtonCallback(MouseClickCallback);
    glfwSetMousePosCallback(MouseMoveCallback);
    glfwSetWindowSizeCallback(Renderer::ResizeCallback);
    glfwSetKeyCallback(KeyCallback);

    lastTime = GetTickCount();

    while( running )
    {
        dt = GetTickCount() - lastTime;
        if(dt == 0){
            dt = 1;
        }
        lastTime = GetTickCount();

        simulation->Update();
        client->Update();
        renderer->Draw();

        running = !glfwGetKey( GLFW_KEY_ESC ) && glfwGetWindowParam( GLFW_OPENED );
        glfwSwapBuffers();

        error = glGetError();
        if(error){
            std::cout<<"OpenGL error: "<<error<<std::endl;
        }
    }

    glfwTerminate();
}
